/**
 * Copyright 2008 by Robert Konigsberg
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the same terms as Perl.
 *
 * @see http://www.perl.com/perl/misc/Artistic.html
 */
package visitor.edge;

import visitor.maze.Direction;
import visitor.maze.Room;

public final class Edge {

  private final Room from;
  private final Room to;
  private final Direction heading;

  /**
   * Creates a new edge instance from a soure room and heading.
   *
   * The destination room is inferred from {@link Room#getExit(Direction)}.
   * @param from
   * @param heading
   * @throws IllegalArgumentException if there's no exit from {@code room}
   * heading in {@code heading} direction.
   */
  public Edge(Room from, Direction heading) {
    this.from = from;
    this.to = from.getExit(heading);
    this.heading = heading;
    if (to == null) {
      throw new IllegalArgumentException(
          "No exit from " + from + " heading " + heading);
    }
  }

  public Room getFrom() {
    return from;
  }

  public Direction getHeading() {
    return heading;
  }

  public Room getTo() {
    return to;
  }

  public void accept(EdgeVisitor visitor) {
    visitor.visit(this);
  }

  @Override
  public int hashCode() {
    int result = 1;
    result = 31 * result + heading.hashCode();
    result = 31 * result + from.hashCode();
    return result;
  }

  @Override
  public boolean equals(Object obj) {
    if (this == obj) {
      return true;
    }
    if (!(obj instanceof Edge)) {
      return false;
    }
    Edge other = (Edge) obj;
    return (
        from.equals(other.from) && heading == other.heading);
  }

  @Override
  public String toString() {
    return String.format("%s heading %s to %s", from, heading, to);
  }
}
